﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "GraphicsStyleConfig.h"
#include "IGraphicsStyleData.h"

#include "pugixml.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace Sample;

#pragma region 读取XML并转换为显示样式数据的辅助函数
namespace
{
    // 从XML文字创建颜色
    Color MakeColor(const wchar_t* colorStr)
    {
        int color = 0;

        std::wistringstream wiss(colorStr);
        wiss >> std::hex >> color;
        bool isOk = wiss.eof() && !wiss.bad() && !wiss.fail();
        if (!isOk) return Color::Black;

        unsigned char r = (color >> 16) & 0xff;
        unsigned char g = (color >> 8) & 0xff;
        unsigned char b = color & 0xff;
        return Color(r, g, b);
    }

    // 从XML文字创建智能颜色数据
    void GetSmartColorMode(const std::wstring& key, SmartColorMode& colorMode)
    {
        if (key == L"inValid")
        {
            colorMode = SmartColorMode::Invalid;
        }
        else if (key == L"useBackgroundColor")
        {
            colorMode = SmartColorMode::SmartUseBackgroundColor;
        }
        else if (key == L"antiBackgroundColor")
        {
            colorMode = SmartColorMode::SmartAntiBackgroundColor;
        }
        else
        {
            DBG_WARN(L"配置文件传入无效参数",L"GDMP",L"2024-03-30");
        }

    }

    // 从XML文字创建样式是否重载的信息
    void GetStyleValiditySettings(const pugi::xml_node& settingsNode
        , IGraphicsStyleDataValiditySettings* pValiditySettings)
    {
        if (!settingsNode || !pValiditySettings)
        {
            return;
        }

        pugi::xml_attribute isColorValidAttr = settingsNode.attribute(L"colorValidity");
        if (isColorValidAttr)
        {
            pValiditySettings->SetColorValidity(isColorValidAttr.as_bool());
        }
        pugi::xml_attribute isTransparencyValidAttr = settingsNode.attribute(L"transparencyValidity");
        if (isTransparencyValidAttr)
        {
            pValiditySettings->SetTransparencyValidity(isTransparencyValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionLineColorValidAttr = settingsNode.attribute(L"projectionLineColorValidity");
        if (isProjectionLineColorValidAttr)
        {
            pValiditySettings->SetProjectionLineColorValidity(isProjectionLineColorValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionLineWidthValidAttr = settingsNode.attribute(L"projectionLineWidthValidity");
        if (isProjectionLineWidthValidAttr)
        {
            pValiditySettings->SetProjectionLineWidthValidity(isProjectionLineWidthValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionLineTypeNameValidAttr = settingsNode.attribute(
            L"projectionLineTypeNameValidity");
        if (isProjectionLineTypeNameValidAttr)
        {
            pValiditySettings->SetProjectionLineTypeNameValidity(isProjectionLineTypeNameValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionLineColorValidAttr = settingsNode.attribute(L"sectionLineColorValidity");
        if (isSectionLineColorValidAttr)
        {
            pValiditySettings->SetSectionLineColorValidity(isSectionLineColorValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionLineWidthValidAttr = settingsNode.attribute(L"sectionLineWidthValidity");
        if (isSectionLineWidthValidAttr)
        {
            pValiditySettings->SetSectionLineWidthValidity(isSectionLineWidthValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionLineTypeNameValidAttr = settingsNode.attribute(L"sectionLineTypeNameValidity");
        if (isSectionLineTypeNameValidAttr)
        {
            pValiditySettings->SetSectionLineTypeNameValidity(isSectionLineTypeNameValidAttr.as_bool());
        }
        pugi::xml_attribute isHiddenLineColorValidAttr = settingsNode.attribute(L"hiddenLineColorValidity");
        if (isHiddenLineColorValidAttr)
        {
            pValiditySettings->SetHiddenLineColorValidity(isHiddenLineColorValidAttr.as_bool());
        }
        pugi::xml_attribute isHiddenLineWidthValidAttr = settingsNode.attribute(L"hiddenLineWidthValidity");
        if (isHiddenLineWidthValidAttr)
        {
            pValiditySettings->SetHiddenLineWidthValidity(isHiddenLineWidthValidAttr.as_bool());
        }
        pugi::xml_attribute isHiddenLineTypeNameValidAttr = settingsNode.attribute(L"hiddenLineTypeNameValidity");
        if (isHiddenLineTypeNameValidAttr)
        {
            pValiditySettings->SetHiddenLineTypeNameValidity(isHiddenLineTypeNameValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionFaceHatchPatternValidAttr = settingsNode.attribute(
            L"projectionFaceHatchPatternValidity");
        if (isProjectionFaceHatchPatternValidAttr)
        {
            pValiditySettings->SetProjectionFaceHatchPatternValidity(isProjectionFaceHatchPatternValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionFaceHatchColorValidAttr = settingsNode.attribute(
            L"projectionFaceHatchColorValidity");
        if (isProjectionFaceHatchColorValidAttr)
        {
            pValiditySettings->SetProjectionFaceHatchColorValidity(isProjectionFaceHatchColorValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionFaceHatchPatternValidAttr = settingsNode.attribute(
            L"sectionFaceHatchPatternValidity");
        if (isSectionFaceHatchPatternValidAttr)
        {
            pValiditySettings->SetSectionFaceHatchPatternValidity(isSectionFaceHatchPatternValidAttr.as_bool());
        }
        pugi::xml_attribute isSmartColorModeValidAttr = settingsNode.attribute(L"smartColorModeValidity");
        if (isSmartColorModeValidAttr)
        {
            pValiditySettings->SetSmartColorModeValidity(isSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionLineSmartColorModeValidAttr = settingsNode.attribute(
            L"projectionLineSmartColorModeValidity");
        if (isProjectionLineSmartColorModeValidAttr)
        {
            pValiditySettings->SetProjectionLineSmartColorModeValidity(
                isProjectionLineSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionLineSmartColorModeValidAttr = settingsNode.attribute(
            L"sectionLineSmartColorModeValidity");
        if (isSectionLineSmartColorModeValidAttr)
        {
            pValiditySettings->SetSectionLineSmartColorModeValidity(isSectionLineSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isHiddenLineSmartColorModeValidAttr = settingsNode.attribute(
            L"hiddenLineSmartColorModeValidity");
        if (isHiddenLineSmartColorModeValidAttr)
        {
            pValiditySettings->SetHiddenLineSmartColorModeValidity(isHiddenLineSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionFaceHatchSmartColorModeValidAttr = settingsNode.attribute(
            L"projectionFaceHatchSmartColorModeValidity");
        if (isProjectionFaceHatchSmartColorModeValidAttr)
        {
            pValiditySettings->SetProjectionFaceHatchSmartColorModeValidity(
                isProjectionFaceHatchSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionFaceHatchSmartColorModeValidAttr = settingsNode.attribute(
            L"sectionFaceHatchSmartColorModeValidity");
        if (isSectionFaceHatchSmartColorModeValidAttr)
        {
            pValiditySettings->SetSectionFaceHatchSmartColorModeValidity(
                isSectionFaceHatchSmartColorModeValidAttr.as_bool());
        }
        pugi::xml_attribute isProjectionLineWidthModeValidAttr = settingsNode.attribute(
            L"projectionLineWidthModeValidity");
        if (isProjectionLineWidthModeValidAttr)
        {
            pValiditySettings->SetProjectionLineWidthModeValidity(isProjectionLineWidthModeValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionLineWidthModeValidAttr = settingsNode.attribute(
            L"sectionLineWidthModeValidity");
        if (isSectionLineWidthModeValidAttr)
        {
            pValiditySettings->SetSectionLineWidthModeValidity(isSectionLineWidthModeValidAttr.as_bool());
        }
        pugi::xml_attribute isHiddenLineWidthModeValidAttr = settingsNode.attribute(
            L"hiddenLineWidthModeValidity");
        if (isHiddenLineWidthModeValidAttr)
        {
            pValiditySettings->SetHiddenLineWidthModeValidity(isHiddenLineWidthModeValidAttr.as_bool());
        }
        pugi::xml_attribute isSectionFaceHatchColorValidAttr = settingsNode.attribute(
            L"sectionFaceHatchColorValidity");
        if (isSectionFaceHatchColorValidAttr)
        {
            pValiditySettings->SetSectionFaceHatchColorValidity(isSectionFaceHatchColorValidAttr.as_bool());
        }
    }

    // 从XML文字创建样式数据
    void GetCommonStyleData(const pugi::xml_node& styleNode, OwnerPtr<IGraphicsStyleData>& opStyleData)
    {
        pugi::xml_attribute isSmartAttr = styleNode.attribute(L"colorSmart");
        if (isSmartAttr)
        {
            opStyleData->SetSmartColorMode(isSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
            opStyleData->SetSectionFaceColorSmartColorMode(isSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
        }
        pugi::xml_attribute colorAttr = styleNode.attribute(L"color");
        if (colorAttr)
        {
            opStyleData->SetColor(MakeColor(colorAttr.as_string()));
            opStyleData->SetSectionFaceColor(MakeColor(colorAttr.as_string()));
        }
        pugi::xml_attribute transparencyAttr = styleNode.attribute(L"transparency");
        if (transparencyAttr)
        {
            opStyleData->SetTransparency(transparencyAttr.as_double());
        }
        pugi::xml_attribute sectionLineColorSmartAttr = styleNode.attribute(L"sectionLineColorSmart");
        if (sectionLineColorSmartAttr)
        {
            opStyleData->SetSectionLineSmartColorMode(sectionLineColorSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
        }
        pugi::xml_attribute sectionLineColorAttr = styleNode.attribute(L"sectionLineColor");
        if (sectionLineColorAttr)
        {
            opStyleData->SetSectionLineColor(MakeColor(sectionLineColorAttr.as_string()));
        }
        pugi::xml_attribute sectionLineWidthAttr = styleNode.attribute(L"sectionLineWidth");
        if (sectionLineWidthAttr)
        {
            opStyleData->SetSectionLineWidth(sectionLineWidthAttr.as_double());
        }
        pugi::xml_attribute sectionLineTypeNameAttr = styleNode.attribute(L"sectionLineTypeName");
        if (sectionLineTypeNameAttr)
        {
            opStyleData->SetSectionLineTypeName(sectionLineTypeNameAttr.as_string());
        }
        pugi::xml_attribute projectionFaceHatchColorSmartAttr = styleNode.attribute(L"projectionFaceHatchColorSmart");
        if (projectionFaceHatchColorSmartAttr)
        {
            opStyleData->SetProjectionFaceHatchSmartColorMode(projectionFaceHatchColorSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
        }
        pugi::xml_attribute projectionFaceHatchColorAttr = styleNode.attribute(L"projectionFaceHatchColor");
        if (projectionFaceHatchColorAttr)
        {
            opStyleData->SetProjectionFaceHatchColor(MakeColor(projectionFaceHatchColorAttr.as_string()));
        }
        pugi::xml_attribute projectionFaceHatchLineWidthAttr = styleNode.attribute(L"projectionFaceHatchLineWidth");
        if (projectionFaceHatchLineWidthAttr)
        {
            opStyleData->SetProjectionFaceHatchLineWidth(projectionFaceHatchLineWidthAttr.as_double());
        }
        pugi::xml_attribute sectionFaceHatchColorSmartAttr = styleNode.attribute(L"sectionFaceHatchColorSmart");
        if (sectionFaceHatchColorSmartAttr)
        {
            opStyleData->SetSectionFaceHatchSmartColorMode(sectionFaceHatchColorSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
        }
        pugi::xml_attribute sectionFaceHatchColorAttr = styleNode.attribute(L"sectionFaceHatchColor");
        if (sectionFaceHatchColorAttr)
        {
            opStyleData->SetSectionFaceHatchColor(MakeColor(sectionFaceHatchColorAttr.as_string()));
        }
        pugi::xml_attribute hiddenLineColorSmartAttr = styleNode.attribute(L"hiddenLineColorSmart");
        if (hiddenLineColorSmartAttr)
        {
            opStyleData->SetHiddenLineSmartColorMode(hiddenLineColorSmartAttr.as_bool() ? SmartColorMode::SmartAntiBackgroundColor : SmartColorMode::Invalid);
        }
        pugi::xml_attribute hiddenLineColorAttr = styleNode.attribute(L"hiddenLineColor");
        if (hiddenLineColorAttr)
        {
            opStyleData->SetHiddenLineColor(MakeColor(hiddenLineColorAttr.as_string()));
        }
        pugi::xml_attribute hiddenLineWidthAttr = styleNode.attribute(L"hiddenLineWidth");
        if (hiddenLineWidthAttr)
        {
            opStyleData->SetHiddenLineWidth(hiddenLineWidthAttr.as_double());
        }
        pugi::xml_attribute hiddenLineTypeNameAttr = styleNode.attribute(L"hiddenLineTypeName");
        if (hiddenLineTypeNameAttr)
        {
            opStyleData->SetHiddenLineTypeName(hiddenLineTypeNameAttr.as_string());
        }
        pugi::xml_attribute isProjectionLineColorAlphaEnabledAttr = styleNode.attribute(L"isProjectionLineColorAlphaEnabled");
        if (isProjectionLineColorAlphaEnabledAttr)
        {
            opStyleData->EnableProjectionLineColorAlpha(isProjectionLineColorAlphaEnabledAttr.as_bool());
        }

        // 1. SmartColorMode
        pugi::xml_attribute smartColorMode = styleNode.attribute(L"smartColorMode");
        if (smartColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(smartColorMode.as_string(), colorMode);
            opStyleData->SetSmartColorMode(colorMode);
        }

        // 2. sectionLineColorMode
        pugi::xml_attribute sectionLineColorMode = styleNode.attribute(L"sectionLineColorMode");
        if (sectionLineColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(sectionLineColorMode.as_string(), colorMode);
            opStyleData->SetSectionLineSmartColorMode(colorMode);
        }

        // 3.projectionFaceHatchColorMode
        pugi::xml_attribute projectionFaceHatchColorMode = styleNode.attribute(L"projectionFaceHatchColorMode");
        if (projectionFaceHatchColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(projectionFaceHatchColorMode.as_string(), colorMode);
            opStyleData->SetProjectionFaceHatchSmartColorMode(colorMode);
        }

        // 4. sectionFaceHatchColorMode
        pugi::xml_attribute sectionFaceHatchColorMode = styleNode.attribute(L"sectionFaceHatchColorMode");
        if (sectionFaceHatchColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(sectionFaceHatchColorMode.as_string(), colorMode);
            opStyleData->SetSectionFaceHatchSmartColorMode(colorMode);
        }

        // 5. hiddenLineColorMode
        pugi::xml_attribute hiddenLineColorMode = styleNode.attribute(L"hiddenLineColorMode");
        if (hiddenLineColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(hiddenLineColorMode.as_string(), colorMode);
            opStyleData->SetHiddenLineSmartColorMode(colorMode);
        }

        // 读取填充样式
        pugi::xml_attribute projectionFaceHatchPattern = styleNode.attribute(L"projectionFaceHatchPattern");
        if (projectionFaceHatchPattern)
        {
            opStyleData->SetProjectionFaceHatchPattern(projectionFaceHatchPattern.as_string());
        }

        pugi::xml_attribute sectionFaceHatchPattern = styleNode.attribute(L"sectionFaceHatchPattern");
        if (sectionFaceHatchPattern)
        {
            opStyleData->SetSectionFaceHatchPattern(sectionFaceHatchPattern.as_string());
        }

        // 读取样式的重载设置
        pugi::xml_node validitySettingsNode = styleNode.child(L"ValiditySettings");
        if (validitySettingsNode)
        {
            OwnerPtr<IGraphicsStyleDataValiditySettings> opSettings = opStyleData->GetDataValiditySettings();
            if (opSettings)
            {
                GetStyleValiditySettings(validitySettingsNode, opSettings.get());
                opStyleData->SetDataValiditySettings(*opSettings);
            }
        }
    }

    // 从XML文字创建前景样式数据
    OwnerPtr<IGraphicsStyleData> GetForegroundGStyleData(const pugi::xml_node& styleNode)
    {
        OwnerPtr<IGraphicsStyleData> opForegroundGStyleData = IGraphicsStyleData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opForegroundGStyleData, L"opStyleData为空",L"GDMP",L"2024-03-30");
        pugi::xml_attribute upProjectionLineColorSmartAttr = styleNode.attribute(L"upProjectionLineColorSmart");
        if (upProjectionLineColorSmartAttr)
        {
            opForegroundGStyleData->SetProjectionLineSmartColorMode(upProjectionLineColorSmartAttr.as_bool() ? gcmp::SmartColorMode::SmartAntiBackgroundColor : gcmp::SmartColorMode::Invalid);
        }
        pugi::xml_attribute upProjectionLineColorAttr = styleNode.attribute(L"upProjectionLineColor");
        if (upProjectionLineColorAttr)
        {
            opForegroundGStyleData->SetProjectionLineColor(MakeColor(upProjectionLineColorAttr.as_string()));
        }
        pugi::xml_attribute upProjectionLineWidthAttr = styleNode.attribute(L"upProjectionLineWidth");
        if (upProjectionLineWidthAttr)
        {
            opForegroundGStyleData->SetProjectionLineWidth(upProjectionLineWidthAttr.as_double());
        }
        pugi::xml_attribute upProjectionLineTypeNameAttr = styleNode.attribute(L"upProjectionLineTypeName");
        if (upProjectionLineTypeNameAttr)
        {
            opForegroundGStyleData->SetProjectionLineTypeName(upProjectionLineTypeNameAttr.as_string());
        }
        pugi::xml_attribute upProjectionLineTypeScaleAttr = styleNode.attribute(L"upProjectionLineTypeScale");
        if (upProjectionLineTypeScaleAttr)
        {
            opForegroundGStyleData->SetProjectionLineTypeScale(upProjectionLineTypeScaleAttr.as_double());
        }

        // 1. upProjectionLineColorMode
        pugi::xml_attribute upProjectionLineColorMode = styleNode.attribute(L"upProjectionLineColorMode");
        if (upProjectionLineColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(upProjectionLineColorMode.as_string(), colorMode);
            opForegroundGStyleData->SetProjectionLineSmartColorMode(colorMode);
        }

        GetCommonStyleData(styleNode, opForegroundGStyleData);
        return opForegroundGStyleData;
    }

    // 从XML文字创建样式数据
    OwnerPtr<IGraphicsStyleData> GetGraphicsStyleData(const pugi::xml_node& styleNode)
    {
        OwnerPtr<IGraphicsStyleData> opBackgroundStyleData = IGraphicsStyleData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opBackgroundStyleData, L"opStyleData为空",L"GDMP",L"2024-03-30");
        pugi::xml_attribute projectionLineColorSmartAttr = styleNode.attribute(L"projectionLineColorSmart");
        if (projectionLineColorSmartAttr)
        {
            opBackgroundStyleData->SetProjectionLineSmartColorMode(projectionLineColorSmartAttr.as_bool() ? gcmp::SmartColorMode::SmartAntiBackgroundColor : gcmp::SmartColorMode::Invalid);
        }
        pugi::xml_attribute projectionLineColorAttr = styleNode.attribute(L"projectionLineColor");
        if (projectionLineColorAttr)
        {
            opBackgroundStyleData->SetProjectionLineColor(MakeColor(projectionLineColorAttr.as_string()));
        }
        pugi::xml_attribute projectionLineWidthAttr = styleNode.attribute(L"projectionLineWidth");
        if (projectionLineWidthAttr)
        {
            opBackgroundStyleData->SetProjectionLineWidth(projectionLineWidthAttr.as_double());
        }
        pugi::xml_attribute projectionLineTypeNameAttr = styleNode.attribute(L"projectionLineTypeName");
        if (projectionLineTypeNameAttr)
        {
            opBackgroundStyleData->SetProjectionLineTypeName(projectionLineTypeNameAttr.as_string());
        }
        pugi::xml_attribute projectionLineTypeScaleAttr = styleNode.attribute(L"projectionLineTypeScale");
        if (projectionLineTypeScaleAttr)
        {
            opBackgroundStyleData->SetProjectionLineTypeScale(projectionLineTypeScaleAttr.as_double());
        }

        // 1. projectionLineColorMode
        pugi::xml_attribute projectionLineColorMode = styleNode.attribute(L"projectionLineColorMode");
        if (projectionLineColorMode)
        {
            SmartColorMode colorMode = SmartColorMode::Invalid;
            GetSmartColorMode(projectionLineColorMode.as_string(), colorMode);
            opBackgroundStyleData->SetProjectionLineSmartColorMode(colorMode);
        }

        GetCommonStyleData(styleNode, opBackgroundStyleData);
        return opBackgroundStyleData;
    }

    // 从XML文字创建类别样式数据
    OwnerPtr<CategoryStyle> GetCategoryStyle(const pugi::xml_node& categoryStyleNode)
    {
        std::wstring categoryUidStr = categoryStyleNode.attribute(L"categoryUid").as_string(L"");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(!categoryUidStr.empty(), L"Styles->CategoryStyles节点需要有categoryUid属性",L"GDMP",L"2024-03-30");
        std::wstring name = categoryStyleNode.attribute(L"name").as_string(L"");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(!name.empty(), L"Styles->CategoryStyles节点需要有name属性",L"GDMP",L"2024-03-30");
        UniIdentity categoryUid = UniIdentity::Create(GuidUtils::FromString(categoryUidStr), L"");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(categoryUid.IsValid(), L"categoryUid无效",L"GDMP",L"2024-03-30");
        bool hasForegroundStyle = categoryStyleNode.attribute(L"hasForegroundStyle").as_bool(false);
        OwnerPtr<IGraphicsStyleData> opStyleData = GetGraphicsStyleData(categoryStyleNode);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opStyleData, L"opStyleData加载失败",L"GDMP",L"2024-03-30");
        OwnerPtr<CategoryStyle> opStyle = NEW_AS_OWNER_PTR(CategoryStyle);
        opStyle->CategoryUid = categoryUid;
        opStyle->Name = name;
        opStyle->HasForegroundStyle = hasForegroundStyle;
        opStyle->m_opStyleData = TransferOwnership(opStyleData);
        return opStyle;
    }
}
#pragma endregion 读取XML并转换为显示样式数据的辅助函数

GraphicsStyleConfig::~GraphicsStyleConfig()
{
}

GraphicsStyleConfig::GraphicsStyleConfig()
{
}

gcmp::OwnerPtr<GraphicsStyleConfig> GraphicsStyleConfig::Load(const std::wstring& configFilePath)
{
    // 加载xml配置文件
    pugi::xml_document doc;
    auto result = doc.load_file(configFilePath.c_str(), pugi::parse_default, pugi::encoding_auto);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(result, L"xml加载出错：" + StringUtil::ToWString(result.description()) + configFilePath,L"GDMP",L"2024-03-30");

    // 读取类别样式
    std::vector<gcmp::OwnerPtr<CategoryStyle>> categoryStyles;
    pugi::xml_node categoryStylesNode = doc.child(L"Styles").child(L"CategoryStyles");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(categoryStylesNode, L"xml缺少Styles->CategoryStyles节点",L"GDMP",L"2024-03-30");
    pugi::xml_node styleNode = categoryStylesNode.first_child();
    while (styleNode)
    {
        OwnerPtr<CategoryStyle> opCategoryStyle = GetCategoryStyle(styleNode);
        if (opCategoryStyle)
        {
            categoryStyles.push_back(TransferOwnership(opCategoryStyle));
        }
        styleNode = styleNode.next_sibling();
    }

    // 构造配置对象
    OwnerPtr<GraphicsStyleConfig> opStyleConfig = NEW_AS_OWNER_PTR(GraphicsStyleConfig);
    opStyleConfig->m_categoryStyles = std::move(categoryStyles);

    return opStyleConfig;
}

const std::vector<gcmp::OwnerPtr<CategoryStyle>>& GraphicsStyleConfig::GetCategoryStyles() const
{
    return m_categoryStyles;
}

